﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace Postnuclear.Dependency.Tree
  {
  /// <summary>
  /// The root of dependencies tree.
  /// Notifies the user if any value inside the expression is changed.
  /// </summary>
  internal sealed class DependencyTree
    : NotifyValueChanged
    {
    #region Public

    // Constructors

    /// <summary>
    /// Initializes a new instance of the <see cref="DependencyTree"/> class.
    /// </summary>
    /// <param name="branches">The branches of dependency tree.</param>
    public DependencyTree(params INotifyValueChanged[] branches)
      {
      Contract.Requires<ArgumentNullException>(branches != null);

      // Root can have no child - the empty tree is created.
      // usually it happens when some fake expressions are used for defaulting
      // For instance if CanExecute handler for the command is not specified the dummy expression is used as the default one,
      // which is constant and leads to creation of the empty tree.
      Branches = branches;
      }

    #endregion

    #region Protected

    // Methods

    /// <summary>
    /// Called when when activation state is changed.
    /// </summary>
    protected override void OnIsActiveChanged()
      {
      if (IsActive)
        {
        Branches.ForEach(branch => branch.ValueChanged += RaiseValueChanged);
        }
      else
        {
        Branches.ForEach(branch => branch.ValueChanged -= RaiseValueChanged);
        }
      }

    #endregion

    #region Private

    // Fields

    private readonly IEnumerable<INotifyValueChanged> Branches;

    #endregion
    }
  }